package com.ssy.lingxi.platform.manage.serviceimpl.mobile;

import cn.hutool.core.collection.CollectionUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.manage.constant.ShelfEnum;
import com.ssy.lingxi.platform.manage.entity.content.*;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdRequest;
import com.ssy.lingxi.platform.manage.model.request.content.CollectRequest;
import com.ssy.lingxi.platform.manage.model.request.content.InformationListReq;
import com.ssy.lingxi.platform.manage.model.response.ContentInformationResponse;
import com.ssy.lingxi.platform.manage.model.response.InformationDetailResp;
import com.ssy.lingxi.platform.manage.model.response.InformationListResp;
import com.ssy.lingxi.platform.manage.repository.*;
import com.ssy.lingxi.platform.manage.service.mobile.IMemberInformationMobileService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * mobile - 自营商家 - 资讯 - 业务实现层
 * @author fhj
 * @version 2.0.0
 * @date 2021/10/25
 */
@Service
public class MemberInformationMobileServiceImpl implements IMemberInformationMobileService {

    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private MemberColumnRepository memberColumnRepository;
    @Resource
    private MemberInformationRepository memberInformationRepository;
    @Resource
    private MemberInformationCollectRepository memberInformationCollectRepository;
    @Resource
    private JdbcTemplate jdbcTemplate;
    @Resource
    private MemberLabelRepository memberLabelRepository;
    @Resource
    private MemberInformationHistoryRepository memberInformationHistoryRepository;


    @Override
    public Wrapper<PageData<InformationListResp>> list(InformationListReq req, Long memberId, Long roleId) {
        //校验
        if(memberId == null || roleId == null) {
            return Wrapper.fail(ResponseCode.PT_PARAMETER_VERIFICATION_FAILED);
        }

        //查询表实体 - 会员资讯
        QMemberInformation memberInformation = QMemberInformation.memberInformation;

        //查询条件构造 - 必要条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(memberInformation.memberId.eq(memberId));
        predicates.and(memberInformation.memberRoleId.eq(roleId));
        predicates.and(memberInformation.status.eq(ShelfEnum.ON_SHELF.getCode()));

        //搜索条件
        if (req.getColumnId() != null) {
            predicates.and(memberInformation.columnId.eq(req.getColumnId()));
        }
        if (CollectionUtil.isNotEmpty(req.getRecommendLabel())) {
            predicates.and(memberInformation.recommendLabel.in(req.getRecommendLabel()));
        }
        if(req.getThirdlyCategoryId() != null) {
            predicates.and(memberInformation.thirdlyCategoryId.eq(req.getThirdlyCategoryId()));
        }
        if(StringUtils.isNotEmpty(req.getKeyword())) {
            List<MemberColumn> columnList = memberColumnRepository.findAllByNameContainingAndStatus(req.getKeyword(), CommonBooleanEnum.YES.getCode());
            //      List<ContentColumn> columnList = contentColumnRepository.findAllByNameContainingAndStatus(req.getKeyword(), CommonBooleanEnum.YES.getCode());
            List<Long> columnIdList = columnList.stream().map(MemberColumn::getId).collect(Collectors.toList());
            predicates.and(
                    memberInformation.title.like("%" + req.getKeyword() + "%")
                            .or(memberInformation.digest.like("%" + req.getKeyword() + "%")
                                    .or(memberInformation.content.like("%" + req.getKeyword() + "%")
                                            .or(memberInformation.firstCategoryName.like("%" + req.getKeyword() + "%")
                                                    .or(memberInformation.secondCategoryName.like("%" + req.getKeyword() + "%")
                                                            .or(memberInformation.thirdlyCategoryName.like("%" + req.getKeyword() + "%")
                                                                    .or(memberInformation.columnId.in(columnIdList)))))))
            );
        }


        //查询
        JPAQuery<InformationListResp> query = jpaQueryFactory.select(
                Projections.bean(
                        InformationListResp.class,
                        memberInformation.id,
                        memberInformation.columnId,
                        memberInformation.title,
                        memberInformation.readCount,
                        memberInformation.collectCount,
                        memberInformation.imageUrl,
                        memberInformation.digest,
                        memberInformation.createTime
                )
        ).from(memberInformation).where(predicates);

        //总记录数
        long totalCount = query.fetchCount();

        //排序（待添加枚举类）
        if (req.getSortType().equals(1)) {
            query.orderBy(memberInformation.createTime.desc());
        }
        if (req.getSortType().equals(2)) {
            query.orderBy(memberInformation.sort.asc());
        }
        if (req.getSortType().equals(3)) {
            query.orderBy(memberInformation.createTime.desc());
        }
        if (req.getSortType().equals(4)) {
            query.orderBy(memberInformation.readCount.desc());
        }
        if (req.getSortType().equals(5)) {
            query.orderBy(memberInformation.collectCount.desc());
        }

        //列表数据
        List<InformationListResp> list = query.offset((long) (req.getCurrent() - 1) * req.getPageSize()).limit(req.getPageSize()).fetch();

        //封装栏目名称
        List<MemberColumn> allColumn = memberColumnRepository.findAll();
        list = list.stream().peek(a -> {
            MemberColumn contentColumn = allColumn.stream().filter(b ->
                    b.getId().equals(a.getColumnId())
            ).findFirst().orElse(new MemberColumn());
            a.setColumnName(contentColumn.getName());
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(totalCount, list));
    }

    @Override
    public Wrapper<InformationDetailResp> detail(CommonIdRequest request, UserLoginCacheDTO user) {
        //根据id获取资讯
        MemberInformation information = memberInformationRepository.findById(request.getId()).orElse(null);
        if (information == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (information.getStatus().equals(ShelfEnum.OFF_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DISABLE);
        }

        //拷贝
        InformationDetailResp resp = new InformationDetailResp();
        BeanUtils.copyProperties(information, resp);

        //栏目名称
        MemberColumn contentColumn = memberColumnRepository.findById(resp.getColumnId()).orElse(new MemberColumn());
        resp.setColumnName(contentColumn.getName());

        //收藏状态
        if (user != null) {
            Boolean collectStatus = memberInformationCollectRepository.existsByInformationIdAndMemberIdAndUserId(information.getId(), user.getMemberId(), user.getUserId());
            resp.setCollectStatus(collectStatus);

            //保存当前登录用户的浏览资讯记录
            MemberInformationHistory  informationHistory = memberInformationHistoryRepository.findByUserIdAndInformationId(user.getUserId(), information.getId());
            if (informationHistory != null) {
                informationHistory.setCreateTime(System.currentTimeMillis());
            }else {
                informationHistory = new MemberInformationHistory();
                informationHistory.setUserId(user.getUserId());
                informationHistory.setSelfMemberId(information.getMemberId());
                informationHistory.setInformationId(information.getId());
            }

            memberInformationHistoryRepository.save(informationHistory);
        }

        //查看详情增加浏览量
        information.setReadCount(information.getReadCount() + 1);
        memberInformationRepository.saveAndFlush(information);

        return Wrapper.success(resp);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Wrapper<Void> collect(CollectRequest request, Long memberId, Long roleId, UserLoginCacheDTO user) {
        if (request.getStatus()) {
            if (memberInformationCollectRepository.existsByInformationIdAndMemberIdAndUserId(request.getInformationId(), user.getMemberId(), user.getUserId())) {
                return Wrapper.fail("不能重复收藏，请刷新页面");
            }
            MemberInformationCollect collect = new MemberInformationCollect();
            collect.setInformationId(request.getInformationId());
            collect.setMemberId(user.getMemberId());
            collect.setUserId(user.getUserId());
            collect.setSelfMemberId(memberId);
            collect.setUrl(request.getUrl());
            memberInformationCollectRepository.saveAndFlush(collect);
        } else {
            memberInformationCollectRepository.deleteByInformationIdAndMemberIdAndUserId(request.getInformationId(), user.getMemberId(), user.getUserId());
        }

        //更新资讯收藏数
        String sql = " UPDATE man_member_information SET collect_count = collect_count ";
        sql += request.getStatus() ? "+ 1 " : " - 1 ";
        sql += "WHERE id = " + request.getInformationId();
        jdbcTemplate.update(sql);

        return Wrapper.success();
    }

    @Override
    public Wrapper<PageData<ContentInformationResponse>> collectList(PageVO request, Long memberId, Long roleId, UserLoginCacheDTO user) {
        //校验
        if(memberId == null || roleId == null) {
            return Wrapper.fail(ResponseCode.PT_PARAMETER_VERIFICATION_FAILED);
        }

        //分页查询当前登录用户收藏资讯信息
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("createTime").descending());
        Page<MemberInformationCollect> result = memberInformationCollectRepository.findAllByMemberIdAndUserIdAndSelfMemberId(user.getMemberId(), user.getUserId(), memberId, page);
        List<MemberInformationCollect> contentInformationResponseList = result.getContent();

        if (CollectionUtil.isNotEmpty(contentInformationResponseList)) {
            List<Long> informationIdList = contentInformationResponseList.stream().map(MemberInformationCollect::getInformationId).collect(Collectors.toList());
            List<MemberInformation> allByIds = memberInformationRepository.findAllById(informationIdList);
            if (CollectionUtil.isNotEmpty(allByIds)) {
                List<MemberColumn> allColumn = memberColumnRepository.findAll();
                List<MemberLabel> allLabel = memberLabelRepository.findAll();

                List<ContentInformationResponse> responses = allByIds.stream().map(a -> {
                    ContentInformationResponse response = new ContentInformationResponse();
                    BeanUtils.copyProperties(a, response);

                    MemberColumn contentColumn = allColumn.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(null);
                    response.setColumnName(contentColumn == null ? "" : contentColumn.getName());

                    if (CollectionUtil.isNotEmpty(a.getLabelIds())) {
                        List<Map<String, Object>> contentLabelList = allLabel.stream()
                                .filter(b -> a.getLabelIds().stream().anyMatch(c -> c.equals(b.getId())))
                                .map(d -> {
                                    Map<String, Object> contentLabel = new HashMap<>();
                                    contentLabel.put("id", d.getId());
                                    contentLabel.put("name", d.getName());
                                    return contentLabel;
                                }).collect(Collectors.toList());
                        response.setContentLabelList(contentLabelList);
                    }

                    Long collectTime = contentInformationResponseList.stream().filter(b -> b.getInformationId().equals(a.getId())).mapToLong(MemberInformationCollect::getCreateTime).findFirst().orElse(0L);
                    response.setCollectTime(collectTime);

                    String url = contentInformationResponseList.stream().filter(b -> b.getInformationId().equals(a.getId())&&b.getUrl()!=null).map(MemberInformationCollect::getUrl).findFirst().orElse("");
                    response.setUrl(url);
                    return response;
                }).sorted(Comparator.comparing(ContentInformationResponse::getCollectTime).reversed()).collect(Collectors.toList());

                return Wrapper.success(new PageData<>(result.getTotalElements(), responses));
            }
        }

        return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
    }

    @Override
    public Wrapper<List<InformationListResp>> history(Long memberId, Long roleId, UserLoginCacheDTO user) {
        //校验
        if(memberId == null || roleId == null) {
            return Wrapper.fail(ResponseCode.PT_PARAMETER_VERIFICATION_FAILED);
        }

        List<MemberInformationHistory> historyList = memberInformationHistoryRepository.findByUserIdAndSelfMemberId(user.getUserId(), memberId, Sort.by("createTime").descending());

        List<Long> informationIdList = historyList.stream().map(MemberInformationHistory::getInformationId).collect(Collectors.toList());

        List<MemberInformation> informationList = memberInformationRepository.findAllById(informationIdList);

        List<MemberColumn> allColumn = memberColumnRepository.findAll();

        List<InformationListResp> respList = informationList.stream().map(a -> {
            InformationListResp resp = new InformationListResp();
            BeanUtils.copyProperties(a, resp);

            MemberColumn contentColumn = allColumn.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(null);
            resp.setColumnName(contentColumn == null ? "" : contentColumn.getName());

            return resp;
        }).collect(Collectors.toList());

        return Wrapper.success(respList);
    }
}
